package com.eol.common.jwt;

import com.eol.common.constants.BaseCommonConstants;
import com.eol.common.exception.BaseException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import com.eol.common.base.BaseResponseCode;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Date;

/**
 * Created with IntelliJ IDEA.
 * User: liulinhui
 * Date: 2018-11-26
 * Time: 15:06
 * Description:  JWTHelper
 */
public class JWTHelper {

    /**
     * 生成token
     *
     * @param tokenData  token元数据
     * @param privateKey 私钥
     * @return String
     */
    public static String generateToken(TokenData tokenData, PrivateKey privateKey) {
        String token = "";
        try {
            token = Jwts.builder()
                    .claim(BaseCommonConstants.JWT_KEY_CREATED, new Date().getTime())
                    .claim(BaseCommonConstants.JWT_KEY_USER_ID, tokenData.getUserId())
                    .claim(BaseCommonConstants.JWT_KEY_REFRESH, tokenData.getV())
                    .signWith(SignatureAlgorithm.RS256, privateKey)
                    .compact();
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException(BaseResponseCode.TOKEN_FAIL_CREATE, e);
        }
        return token;
    }

    /**
     * 公钥解析token
     *
     * @param token token
     * @return
     */
    private static Jws<Claims> parserToken(String token, PublicKey publicKey) {
        try {
            return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BaseException(BaseResponseCode.TOKEN_INVALID, e);
        }
    }

    /**
     * 获取token中的信息
     *
     * @param token     token
     * @param publicKey 公钥地址
     * @return TokenData
     */
    public static TokenData getInfoFromToken(String token, PublicKey publicKey) {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();
        return TokenData
                .builder()
                .userId(getObjectValue(body.get(BaseCommonConstants.JWT_KEY_USER_ID)))
                .t(Long.parseLong(getObjectValue(body.get(BaseCommonConstants.JWT_KEY_CREATED))))
                .v(Long.parseLong(getObjectValue(body.get(BaseCommonConstants.JWT_KEY_REFRESH))))
                .build();
    }

    /**
     * object 转 String
     *
     * @param obj obj
     * @return String
     */
    private static String getObjectValue(Object obj) {
        return obj == null ? "" : obj.toString();
    }

}
